package cn.tj212.xiaoyin.common.orm;

import cn.tj212.xiaoyin.common.util.BeanUtil;
import org.apache.commons.lang.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 为mybatis准备动态sql
 */
public class MybatisJdbcHelper {

    public static <T> String getByIdSql(Class<T> eneityClass, String... fieldNames) {
        String sql = MybatisJdbcHelper.querySql(eneityClass, null, fieldNames);
        sql += " WHERE ID= #{param2}";
        return sql;
    }

    public static <T, E> String queryByIdSql(Class<T> entityClass, E[] ids, String... fieldNames) {
        StringBuilder where = new StringBuilder();
        for (E id : ids
                ) {
            where.append(id + ",");
        }
        String sql = querySql(entityClass, null, fieldNames);
        return sql + " WHERE ID IN (" + where.toString().substring(0, where.length() - 1) + ")";
    }

    public static <T> String countSql(Class<T> entityClass, QueryFilter filter) {
        String tableName = BeanUtil.getTableName(entityClass).toUpperCase();
        StringBuilder sql = new StringBuilder("SELECT COUNT(1) FROM " + tableName);
        if (filter != null) {
            if (!StringUtils.isEmpty(filter.getWhere())) {
                sql.append(" WHERE " + filter.getWhere());
            }
        }
        return sql.toString();
    }

    public static <T> String createSql(Class<T> entityClass) {
        Map<String, String> map = BeanUtil.getAllFieldColumns(entityClass);
        String tableName = BeanUtil.getTableName(entityClass).toUpperCase();
        StringBuilder sb = new StringBuilder("INSERT INTO " + tableName);
        Object[] fieldNames = map.keySet().toArray();
        Object[] colNames = map.values().toArray();
        sb.append(" ( " + join(colNames).toUpperCase() + " )");
        sb.append(" VALUES ");
        sb.append(" ( " + join2(fieldNames) + " )");
        return sb.toString();
    }

    public static <T> Map<String, String> createAllSqlMap(Class<T> entityClass) {
        Map<String, String> map = BeanUtil.getAllFieldColumns(entityClass);
        String tableName = BeanUtil.getTableName(entityClass).toUpperCase();
        StringBuilder sql1 = new StringBuilder("INSERT INTO " + tableName);
        Object[] fieldNames = map.keySet().toArray();
        Object[] colNames = map.values().toArray();
        sql1.append(" ( " + join(colNames).toUpperCase() + " )");
        sql1.append(" VALUES ");
        String sql2 = " ( " + join3(fieldNames) + " )";
        Map<String, String> rstMap = new HashMap<String, String>();
        rstMap.put("sql1", sql1.toString());
        rstMap.put("sql2", sql2);
        return rstMap;
    }

    public static <T> String updateSql(Class<T> entityClass, boolean byId, QueryFilter filter, String... fieldNames) {
        Map<String, String> map = BeanUtil.getAllFieldColumns(entityClass);
        String tableName = BeanUtil.getTableName(entityClass).toUpperCase();
        StringBuilder sql = new StringBuilder("UPDATE " + tableName + " SET ");
        if (fieldNames != null && fieldNames.length > 0) {
            for (String name : fieldNames
                    ) {
                String column = BeanUtil.fieldToColumn(name);
                sql.append(" " + column.toUpperCase() + " ={#param2." + name + "},");
            }
        } else {
            for (String s : map.keySet()
                    ) {
                if (!"id".equals(s) && !"createUser".equals(s)&&!"createTime".equals(s)&&!"del".equals(s)){
                    sql.append(" "+map.get(s).toString().toUpperCase()+" ={#param2." + s + "},");
                }
            }
        }
        String updateSql=sql.toString().substring(0,sql.length()-1);
        if (byId){//根据Id更新对象
            updateSql+=" WHERE ID = #{param2.id}";
        }else {//更新所有，或者根据条件更新对象
            if (filter!=null){
                if (StringUtils.isEmpty(filter.getWhere())){
                    updateSql+= " WHERE "+filter.getWhere();
                }
            }
        }
        return updateSql;
    }

    private static <T> String querySql(Class<T> entityClass, QueryFilter filter, String[] fieldNames) {
        StringBuilder sql = new StringBuilder("SELECT ");
        String tableName = BeanUtil.getTableName(entityClass).toUpperCase();
        if (fieldNames != null && fieldNames.length > 0) {
            String columnSql = "";
            for (String name : fieldNames
                    ) {
                String column = BeanUtil.fieldToColumn(name);
                columnSql += " " + column.toUpperCase() + ",";
            }
            sql.append(columnSql.substring(0, columnSql.length() - 1));
        } else {
            sql.append(" * ");
        }
        sql.append(" FROM " + tableName);
        if (filter != null) {
            if (!StringUtils.isEmpty(filter.getWhere())) {
                sql.append(" WHERE " + filter.getWhere());
            }
            if (!StringUtils.isEmpty(filter.getSort())) {
                sql.append(" ORDER BY " + filter.getSort());
            }
        }
        return sql.toString();
    }

    private static <T> String deleteSql(Class<T> entityClass,boolean byId,QueryFilter filter){
        String tableName=BeanUtil.getTableName(entityClass).toUpperCase();
        StringBuilder sql=new StringBuilder("DELETE FROM "+tableName);
        if (byId){//根据ID更新对象
            sql.append(" WHERE ID = #{param2.id} ");
        }else {
            if (filter!=null){
                if (!StringUtils.isEmpty(filter.getWhere())){
                    sql.append(" WHERE "+filter.getWhere());
                }
            }
        }
        return sql.toString();
    }

    public static String join(Object[] arr) {
        StringBuilder sb = new StringBuilder();
        for (Object s : arr
                ) {
            sb.append(s + ",");
        }
        String str = sb.toString();
        return str.substring(0, str.length() - 1);
    }

    private static String join2(Object[] arr) {
        StringBuilder sb = new StringBuilder();
        for (Object s : arr
                ) {
            sb.append("{#param2." + s + "},");
        }
        String str = sb.toString();
        return str.substring(0, str.length() - 1);
    }

    private static String join3(Object[] arr) {
        StringBuilder sb = new StringBuilder();
        for (Object s : arr
                ) {
            sb.append("{#item." + s + "},");
        }
        String str = sb.toString();
        return str.substring(0, str.length() - 1);
    }
}
